package node_management_logic

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/crypto/ssh"
	"strings"
	"sync"
	"yunzhan/api-server/internal/svc"
	"yunzhan/api-server/internal/types"

	agent "yunzhan/rpc-server/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type CheckSudoPrivLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewCheckSudoPrivLogic 检查sudo权限
func NewCheckSudoPrivLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckSudoPrivLogic {
	return &CheckSudoPrivLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

// CheckSudoPriv 使用协程并行检查多个节点的 sudo 权限
func (l *CheckSudoPrivLogic) CheckSudoPriv(req *types.CheckSudoPrivRequest) (*agent.DeployResponse, error) {
	if req.Nodes == nil {
		return &agent.DeployResponse{
			Code:    500,
			Message: "未配置节点信息, 无法执行sudo权限检查",
		}, errors.New("未配置节点信息, 无法执行sudo权限检查")
	}

	var wg sync.WaitGroup
	resultCh := make(chan string, len(req.Nodes))
	errCh := make(chan string, len(req.Nodes))

	// 使用单独的goroutine来处理每个节点的检查
	for _, node := range req.Nodes {
		wg.Add(1)
		go func(node *agent.NodeInfo) {
			defer wg.Done()

			// 创建SSH客户端配置
			config := &ssh.ClientConfig{
				User: node.Username,
				Auth: []ssh.AuthMethod{
					ssh.Password(node.Password),
				},
				HostKeyCallback: ssh.InsecureIgnoreHostKey(),
			}

			addr := fmt.Sprintf("%s:%s", node.Host, node.Port)
			client, err := ssh.Dial("tcp", addr, config)
			if err != nil {
				logx.Errorf("%s: 连接失败: %v", node.Host, err)
				errCh <- fmt.Sprintf("%s: 连接失败: %v", node.Host, err)
				return
			}
			defer client.Close()

			// 使用 SSH 客户端执行命令
			session, err := client.NewSession()
			if err != nil {
				logx.Errorf("%s: 创建会话失败: %v", node.Host, err)
				errCh <- fmt.Sprintf("%s: 创建会话失败: %v", node.Host, err)
				return
			}
			defer session.Close()

			// 执行 sudo 权限检查命令
			checkCommand := "sudo -n true"
			output, err := session.CombinedOutput(checkCommand)
			if err != nil {
				logx.Errorf("%s: 执行 sudo 权限检查命令失败: %v, output: %s", node.Host, err, output)
				errCh <- fmt.Sprintf("%s: 执行 sudo 权限检查命令失败: %v, output: %s", node.Host, err, output)
				return
			}

			if string(output) != "" {
				logx.Errorf("%s: 当前用户 %s 未配置sudo免密权限", node.Host, node.Username)
				resultCh <- fmt.Sprintf(`%s: 当前用户 %s 未配置sudo免密权限。
请按照以下步骤配置 sudo 免密权限:
1. 以 root 用户或具有 sudo 权限的用户登录系统。
2. 编辑 sudoers 文件: sudo visudo 或 sudo vi /etc/sudoers
3. 在文件中添加以下行: %s ALL=(ALL) NOPASSWD: ALL
4. 保存并退出编辑器。`, node.Host, node.Username, node.Username)
			} else {
				logx.Infof("%s: 当前用户 %s 已配置sudo免密权限", node.Host, node.Username)
				resultCh <- fmt.Sprintf("%s: 当前用户 %s 已配置sudo免密权限", node.Host, node.Username)
			}

		}(node)
	}

	wg.Wait()
	close(resultCh)
	close(errCh)

	var results []string
	var resErrors []string
	for result := range resultCh {
		results = append(results, result)
	}
	for err := range errCh {
		resErrors = append(resErrors, err)
	}

	combinedResults := fmt.Sprintf(`sudo权限检查结果:
%s

错误信息:
%s
`, strings.Join(results, "\n"), strings.Join(resErrors, "\n"))

	return &agent.DeployResponse{
		Code:    200,
		Message: combinedResults,
	}, nil
}
